<template>
    <el-dialog
        :model-value="props.value"
        :title="readOnly ? '属性详情' : props.detail ? '修改属性' : '新建属性'"
        width="1000px"
        @closed="props.closed"
    >
        <el-form ref="table" :model="form" :rules="rules" label-width="120px" :disabled="props.readOnly">
            <el-row :gutter="20">
                <el-col :span="12">
                    <el-form-item label="属性名称" prop="displayName">
                        <el-input v-model.trim="form.displayName" placeholder="请输入属性名称" maxlength="50" />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="模型名称" prop="modelName">
                        <el-input
                            :model-value="props.modelDetail?.displayName || props.detail?.objectName"
                            placeholder="请输入模型名称"
                            disabled
                        />
                    </el-form-item>
                </el-col>

                <el-col :span="12">
                    <el-form-item label="标识符" prop="attributeName">
                        <el-input
                            v-model="form.attributeName"
                            placeholder="请输入标识符"
                            maxlength="50"
                            :disabled="!!props.detail"
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="显示顺序" prop="showOrder">
                        <el-input-number v-model="form.showOrder" />
                    </el-form-item>
                </el-col>

                <el-col :span="12">
                    <el-form-item label="属性类型" required prop="attributeType">
                        <el-radio-group
                            v-model="form.attributeType"
                            :disabled="
                                props.modelDetail?.modifierType !== 'EXTENDED' ||
                                (props.detail && props.modelDetail?.activeState === 'ACTIVATED')
                            "
                        >
                            <template v-if="props.modelDetail?.modifierType === 'ABSTRACT'">
                                <el-radio value="MODEL">父模型属性</el-radio>
                            </template>
                            <template v-if="props.modelDetail?.modifierType === 'EXTENDED'">
                                <el-radio value="MODEL">父模型属性</el-radio>
                                <el-radio value="CHILD_MODEL">私有属性</el-radio>
                            </template>
                            <template v-if="props.modelDetail?.modifierType === 'SINGLE'">
                                <el-radio value="MODEL">模型属性</el-radio>
                            </template>
                        </el-radio-group>
                    </el-form-item>
                </el-col>

                <el-col :span="12">
                    <el-form-item label="是否必填" required prop="required">
                        <el-radio-group v-model="form.required">
                            <el-radio :value="true">是</el-radio>
                            <el-radio :value="false">否</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </el-col>

                <el-col :span="12">
                    <el-form-item label="读写标识" required prop="rwFlag">
                        <el-radio-group v-model="form.rwFlag">
                            <el-radio value="READ">只读</el-radio>
                            <el-radio value="WRITE">只写</el-radio>
                            <el-radio value="READWRITE">读写</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </el-col>

                <!--                <el-col :span="12">-->
                <!--                    <el-form-item label="全局搜索" required prop="keywordEnabled">-->
                <!--                        <el-radio-group v-model="form.keywordEnabled">-->
                <!--                            <el-radio :value="true">允许</el-radio>-->
                <!--                            <el-radio :value="false">不允许</el-radio>-->
                <!--                        </el-radio-group>-->
                <!--                    </el-form-item>-->
                <!--                </el-col>-->

                <el-col :span="12">
                    <el-form-item label="列表查询" required prop="searchEnabled">
                        <el-radio-group v-model="form.searchEnabled">
                            <el-radio :value="true">允许</el-radio>
                            <el-radio :value="false">不允许</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </el-col>

                <el-col :span="12">
                    <el-form-item label="建立索引" required prop="createIndex">
                        <el-radio-group disabled v-model="form.createIndex">
                            <el-radio :value="true">允许</el-radio>
                            <el-radio :value="false">不允许</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </el-col>

                <el-col :span="12">
                    <el-form-item label="列类型" required prop="columnType">
                        <el-select
                            v-model="form.columnType"
                            placeholder="请选择列类型"
                            :disabled="props.detail && props.modelDetail?.activeState === 'ACTIVATED'"
                        >
                            <el-option label="ATTRIBUTE" value="ATTRIBUTE" />
                            <el-option label="FIELD" value="FIELD" />
                        </el-select>
                    </el-form-item>
                </el-col>

                <el-col :span="24">
                    <el-form-item label="页面备注" prop="helpText">
                        <el-input v-model="form.helpText" placeholder="请输入页面备注" maxlength="50" />
                    </el-form-item>
                </el-col>

                <el-col :span="24">
                    <el-form-item label="描述" prop="description">
                        <el-input
                            v-model="form.description"
                            :rows="4"
                            type="textarea"
                            placeholder="请输入描述"
                            maxlength="200"
                            show-word-limit
                        />
                    </el-form-item>
                </el-col>
            </el-row>

            <el-row :gutter="20">
                <div class="divider">设置数据类型</div>
                <el-col :span="24">
                    <el-form-item label="数据类型" required prop="typeName">
                        <el-select
                            :disabled="props.detail && props.modelDetail?.activeState === 'ACTIVATED'"
                            v-model="form.typeName"
                            placeholder="请选择数据类型"
                            @change="onTypeNameChange"
                        >
                            <el-option-group
                                v-for="group in typeNameList"
                                :key="group.label"
                                :label="group.label || '其他'"
                            >
                                <el-option
                                    v-for="item in group.options"
                                    :label="`${item.displayName} - ${item.typeName}`"
                                    :value="item.typeName"
                                    :key="item.id"
                                />
                            </el-option-group>
                        </el-select>
                    </el-form-item>
                </el-col>

                <el-col :span="12" v-for="item in uiSchema" :key="item.name">
                    <FormSetterItem
                        :item="item"
                        :prop="['additionalDefinition', item.name]"
                        v-model="form.additionalDefinition[item.name]"
                    />
                </el-col>

                <div class="divider">设置默认值</div>
                <AttributeDefaultValueConfig :form="form" />
            </el-row>
        </el-form>
        <template #footer v-if="!props.readOnly">
            <div class="dialog-footer">
                <el-button @click="props.close">取消</el-button>
                <el-button type="primary" @click="onSubmit" :loading="loading">确定</el-button>
            </div>
        </template>
    </el-dialog>
</template>
<script lang="ts" setup>
import { type PopupBoxProps, tryJsonParse } from '@great/utils';
import { modelService } from '@great/services';
import { computed, reactive, watchEffect } from 'vue';
import type { FormInstance, FormRules } from 'element-plus';
import { useRequest } from 'vue-request';
import { FormSetterItem, type MaterialProps } from '@great/designer';
import AttributeDefaultValueConfig from '@/components/AttributeDefaultValueConfig.vue';

interface IProps extends PopupBoxProps {
    readOnly?: boolean;
    modelDetail?: Record<string, any>;
    detail?: Record<string, any>;
    callback?: () => void;
    attributeTypeList: Record<string, any>;
}

const props = defineProps<IProps>();
const formRef = useTemplateRef<FormInstance>('table');
const uiSchema = ref<MaterialProps[]>(tryJsonParse(props.detail?.uiSchema, []));

const form = reactive({
    attributeName: '',
    modelName: props.modelDetail?.objectName,
    displayName: '',
    showOrder: 0,
    attributeType: 'MODEL',
    required: false,
    keywordEnabled: false,
    helpText: '',
    description: '',
    rwFlag: 'READ',
    searchEnabled: true,
    createIndex: false,
    defaultValueType: undefined,
    defaultValue: undefined,
    fieldType: '',
    typeName: '',
    columnType: '',
    ...props.detail,
    additionalDefinition: tryJsonParse(props.detail?.additionalDefinition, {})
});

const rules = reactive<FormRules<any>>({
    displayName: [{ required: true, message: '请输入属性名称', trigger: ['change'] }],
    attributeName: [
        { required: true, message: '请输入标识符', trigger: ['change'] },
        {
            validator: (rule, value, callback) => {
                // 字母数字组合且符合驼峰命名
                if (!/^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$/.test(value)) {
                    return callback(new Error('必须是字母数字组合且符合驼峰命名法'));
                }
                callback();
            },
            trigger: 'change'
        }
    ],
    typeName: [{ required: true, message: '请选择数据类型', trigger: ['change'] }],
    columnType: [{ required: true, message: '请选择列类型', trigger: ['change'] }]
});

const { run, loading } = useRequest(
    () => {
        if (props.detail) {
            return modelService.attribute.update({
                ...props.detail,
                ...form,
                additionalDefinition: JSON.stringify(form.additionalDefinition || {}),
                objectName: props.modelDetail?.objectName
            });
        }
        return modelService.attribute.create({
            ...form,
            additionalDefinition: JSON.stringify(form.additionalDefinition || {}),
            objectName: props.modelDetail?.objectName
        });
    },
    {
        manual: true,
        onSuccess() {
            props.close();
            props.callback?.();
        }
    }
);

const typeNameList = computed(() => {
    const types = {};
    Object.entries(props.attributeTypeList)
        .filter(([_, value]) => value.iotField)
        .forEach(([key, value]: any) => {
            types[value.persistType] = types[value.persistType] || [];
            types[value.persistType].push(value);
        });
    return Object.keys(types).map(label => {
        return {
            label,
            options: types[label]
        };
    });
});

function onTypeNameChange(value: string) {
    form.additionalDefinition = {};
    form.fieldType = props.attributeTypeList[value].iotField;
}

function onSubmit() {
    formRef.value?.validate(valid => {
        valid && run();
    });
}

watchEffect(() => {
    uiSchema.value = JSON.parse(props.attributeTypeList?.[form.typeName]?.uiSchema || '[]');
});
</script>

<style lang="scss" scoped>
:deep(.form-setter-item .el-form-item__content) {
    margin-bottom: 0;
}
:deep(.el-select-group .el-select-dropdown__item) {
    padding-left: 40px;
}
.divider {
    border-bottom: var(--el-border);
    width: 100%;
    padding-bottom: 10px;
    padding-top: 20px;
    margin: 0 30px 20px;
    font-size: 14px;
    font-weight: 600;
}

:deep(.switch-config-setter) {
    & > .el-form-item {
        margin-bottom: 18px !important;
    }
}
:deep(.object-setter > .list > .el-form-item) {
    margin-bottom: 18px;
    flex: auto;
    width: 100%;
}
:deep(.object-setter .object-setter .list > .el-form-item) {
    margin-bottom: 18px;
    flex: auto;
    width: 100%;
    &:not(:last-child) {
        margin-bottom: 6px !important;
    }
    .el-form-item__label {
        width: auto !important;
    }
}
</style>
